package com.fowo.api.sys.performance.writer;

import com.fowo.api.common.util.DateUtils;
import com.fowo.api.sys.performance.model.PerformanceLogModel;
import com.fowo.api.sys.performance.properties.PerformanceLogProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;

@Slf4j
@Component
public class TextPerformanceLogWriter extends AbstractBatchPerformanceLogWriter {

    public TextPerformanceLogWriter(PerformanceLogProperties properties) {
        super(properties);
    }

    @Override
    void batchWrite(List<PerformanceLogModel> logs) {
        try (OutputStreamWriter writer = getLogOutputWriter()) {
            for (PerformanceLogModel log : logs) {
                writeLog(writer, log);
            }
            writer.flush();
        } catch (Exception e) {
            log.error("批量写入日志时发生问题", e);
        }
    }

    private OutputStreamWriter getLogOutputWriter() throws IOException {
        String dir = properties.getLogDir();
        if (!StringUtils.hasText(dir)) {
            dir = "./logs/performance";
        }
        File dirFile = new File(dir);
        if (!dirFile.exists()) {
            if(!dirFile.mkdirs()) {
                throw new IOException("无法创建性能日志输出文件夹！");
            }
        }
        String fileName = String.format("%s.log", DateUtils.toDateString(new Date()));
        return new OutputStreamWriter(new FileOutputStream(new File(dirFile, fileName), true), StandardCharsets.UTF_8);
    }

    private void writeLog(OutputStreamWriter writer, PerformanceLogModel log) throws IOException {
        String line = formatLogLine(log);
        writer.write(line + "\r\n");
    }

    private String formatLogLine(PerformanceLogModel log) {
        StringBuilder sb = new StringBuilder();
        sb.append(log.getId()).append("\t");
        sb.append(DateUtils.toString(log.getStartTime(), "yyyy-MM-dd HH:mm:ss.SSS")).append("\t");
        if (log.getEndTime() != null) {
            sb.append(DateUtils.toString(log.getEndTime(), "yyyy-MM-dd HH:mm:ss.SSS")).append("\t");
            sb.append(log.getEndTime().getTime() - log.getStartTime().getTime()).append("\t");
        } else {
            sb.append("null\t-1\t");
        }
        sb.append(log.getInvokeTarget()).append("\t");
        sb.append(log.getStatus());
        return sb.toString();
    }
}
